#include "Code.h"
namespace compiler{
#pragma region Lable
	Lable::Lable()
	{
		int static lable(0);
		this->l=lable++;
	}
	string* Lable::to_string()
	{
		ostringstream st;
		st<<"L"<<l;
		return new string(st.str());
	}
	map<int,Mcode* > lable_to_mcode;
	void build_map(list<Func_token* > &_code)
	{
		list<Func_token* >::iterator fit;
		for(fit=_code.begin();fit!=_code.end();fit++)
		{
			Func_token *f=*fit;
			list<Mcode* >::iterator mit;
			Mcode *m;
			for(mit=f->codes.begin();mit!=f->codes.end();mit++)
			{
				m=*mit;
				if(m->lable!=NULL)
					lable_to_mcode[m->lable->l]=m;
			}
		}
	}
	Mcode* find_mcode(int l)
	{	
		map<int,Mcode * >::iterator it;
		it=lable_to_mcode.find(l);
		return it->second;
	}
#pragma endregion Lable


#pragma region Token

	Token::Token(string *s){
		this->init();
		this->s=s;
	}
	Token::Token(char *s){
		this->init();
		this->s=new string(s);
	}
	Token::Token(){
		this->init();
	}
	Token::~Token()
	{
		if(s!=NULL) delete s;
		if(value!=NULL) delete value;
	}
	Token *Token::clone()
	{
		return NULL;
	}
	void Token::init(){
		this->s=NULL;
		this->cons=false;
		this->type=0;
		this->func=false;
		this->loc=0;
		this->reg=0;
		this->glo_id=false;
	}
#pragma endregion Token
	

#pragma region Func_token
	
	Func_token::Func_token(string *s)
	{
		this->init();
		this->s=s;
	}
	Func_token::Func_token(char *s)
	{	
		this->init();
		this->s=new string(s);
	}
	Func_token::Func_token()
	{
		this->init();
	}
	Func_token::Func_token(Token *t)
	{
		this->init();
		this->cons=false;
		this->func=true;
		this->glo_id=true;
		this->s=t->s;
		this->type=t->type;
	}
	void Func_token::init()
	{
		this->func=true;
		this->argc=0;
	}
	Func_token::~Func_token()
	{
		delete argv[10];
	}
#pragma endregion Func_token

#pragma region ACode
	ACode::ACode()
	{
		op=NULL; lable=NULL; des=NULL; src=NULL;
	}
	ACode::ACode(const char *op,const char *des,const char *src)
	{
		string *s;
		string sop(op);
		lable=NULL;
		if(op!=NULL)
			this->op=new string(op);
		else 
			this->op=NULL;
		if(des!=NULL)
		{
			/*if(sop=="cmp")
			{
				s=new string(" dword ptr ");
				s->append(des);
				this->des=s;
			}
			else(*/
				this->des=new string(des);
		}
		else
			this->des=NULL;
		if(src)
			this->src=new string(src);
		else
			this->src=NULL;
	}
	bool ACode::optimize()
	{
		if((int)op*(int)src*(int)des==0) return false;
		if((*op=="mov")&&
			(*src==*des)) return true;
		return false;
	}
	string* ACode::to_string()
	{
		if(optimize()) return new string(" ");
		string *s=new string();
		if(lable!=NULL) 
		{
			s->append(*lable);
			s->append(": \n");
			return s;
		}
		s->append("\t");
		if(op!=NULL) 
		{
			s->append(*op);
			s->append(" ");
		}
		if(des!=NULL)
		{
			s->append(*des);
			s->append(" ");
			if(src!=NULL)
				s->append(", ");
		}
		if(src!=NULL)
		{
			s->append(*src);
			s->append(" ");
		}
		return s;
	}
	ACode::~ACode()
	{
		if(op!=NULL) delete op;
		if(des!=NULL) delete des;
		if(src!=NULL) delete src;
	}
#pragma endregion ACode
#pragma region Mcode
	Mcode::Mcode(int op,Token *e1,Token *e2,Token *r){
		this->e1=e1;
		this->e2=e2;
		this->op=op;
		this->r=r;
		this->jl=NULL;
		this->lable=NULL;
		this->begin=false;
		this->end=false;
	}
	Mcode::~Mcode()
	{
		if(e1!=NULL) delete e1;
		if(e2!=NULL) delete e2;
		if(r!=NULL) delete r;
		if(lable!=NULL) delete lable;
		if(jl!=NULL) delete jl;
	}
	void Mcode::set_lable(Lable *lable){
		this->lable=lable;
	}


#pragma endregion Mcode
#pragma region Block
	Block::Block()
	{

	}
	Block::~Block()
	{

	}

#pragma endregion Block
}
